# -*- coding: utf-8 -*-
# &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
# D7Cl0ud360
# 邮箱: 18656042877@163.com
# 作者：'sugar'
# 公司网址： http://www.dtcloud360.com/
# Copyright 中亿丰信息科技(苏州)有限公司
# 日期：2023/5/10 10:20
# &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
import logging
from copy import deepcopy
from dtcloud import http
from dtcloud.addons.rest_controller.handlers import RestController
from ..serializer.org import OrgBodyModel

_logger = logging.getLogger(__name__)


class OrganizationController(RestController):
    _model = 'dt.organization'
    _method_map = {
        'list': 'GET',
        'create': 'POST',
        'update': 'PUT',
        'destroy': 'DELETE',
    }
    _default_auth = 'token'
    _type = 'jsonify'
    _prefix = "/api"
    # _kwargs = {'permit': True}

    def list(self, **kwargs):
        model = http.request.env[self._model]
        domain = []
        if kwargs.get('name'):
            domain.append(('name', 'ilike', kwargs['name']))

        res = model.sudo().search_read(domain, fields=('id', 'name', 'parentId',
                                                       'code', 'status', 'seq_no', 'leader',
                                                       'email', 'mobile', 'user_count'),
                                       order="parentId desc,seq_no asc")

        # 调整上下级关系
        org_map = {org['id']: org for org in res if org['parentId']}
        root_org_map = {org['id']: org for org in res if not org['parentId']}

        del_key = []
        org_map_copy = deepcopy(org_map)
        for name, org in org_map_copy.items():
            if org['parentId'][0] in org_map:
                if not org_map[org['parentId'][0]]['status']:
                    org_map[name]['no_use'] = True
                org_map[org['parentId'][0]]['user_count'] += org_map[name]['user_count']
                org_map[org['parentId'][0]].setdefault('children', []).append(org_map[name])
                del_key.append(name)
                # del org_map[name]

        for key in del_key:
            del org_map[key]

        for name, org in org_map.items():
            if org['parentId'][0] in root_org_map:
                if not root_org_map[org['parentId'][0]]['status']:
                    org['no_use'] = True
                root_org_map[org['parentId'][0]]['user_count'] += org['user_count']
                root_org_map[org['parentId'][0]].setdefault("children", []).append(org)
            else:
                root_org_map[name] = org

        return self.make_response(list(root_org_map.values()))

    def create(self, **data):
        data = OrgBodyModel(**data).dict(exclude_none=True)
        domains = [('parentId', '=', data.get("parentId")), ('seq_no', '=', data['seq_no'])]
        if http.request.env[self._model].sudo().search_count(domains):
            return self.make_response(None, status=-1, msg="排序值在同级部门中已存在!")
        if http.request.env[self._model].sudo().search_count([('code', '=', data['code'])]):
            return self.make_response(None, status=-1, msg='系统已存在该编码!')
        if http.request.env[self._model].sudo().search_count([('name', '=', data['name'])]):
            return self.make_response(None, status=-1, msg='系统已存在该部门名称!')

        res = http.request.env[self._model].sudo().create(data)
        return self.make_response(res.id if res else None)

    def _iter_child(self, org, prg_ids):
        for child in org.child_ids:
            if child.user_count and child.user_count > 0:
                raise Exception(f"当前部门子部门`{child.name}`下存在员工,请先将其移除再进行关闭!")
        for child in org.child_ids:
            prg_ids.append(child.id)
            self._iter_child(child, prg_ids)

    def update(self, req_id, **data):
        if data.get('status') is False:
            org = http.request.env[self._model].sudo().browse(int(req_id))
            if org.user_count and org.user_count > 0:
                return self.make_response(None, status=-1, msg="当前部门下存在员工,请先将其移除再进行关闭!")
            # 遍历子集部门
            prg_ids = []
            self._iter_child(org, prg_ids)
            if prg_ids:
                _logger.info(f"更新子级部门{prg_ids}")
                orgs = http.request.env[self._model].sudo().browse(prg_ids)
                orgs.write({
                    "status": False
                })

        if 'status' in data and len(data) == 1:
            return super().update(req_id, **data)

        data = OrgBodyModel(**data).dict()
        domains = [('parentId', '=', data.get("parentId")), ('seq_no', '=', data['seq_no']), ('id', '!=', int(req_id))]
        if http.request.env[self._model].sudo().search_count(domains):
            return self.make_response(None, status=-1, msg="排序值在同级部门中已存在!")
        if http.request.env[self._model].sudo().search_count([('code', '=', data['code']), ('id', '!=', int(req_id))]):
            return self.make_response(None, status=-1, msg='系统已存在该编码!')
        if http.request.env[self._model].sudo().search_count([('name', '=', data['name']), ('id', '!=', int(req_id))]):
            return self.make_response(None, status=-1, msg='系统已存在该部门名称!')

        return super().update(req_id, **data)

    def destroy(self, req_id):
        org = http.request.env[self._model].sudo().browse(int(req_id))
        if org.user_count and org.user_count > 0:
            return self.make_response(None, status=-1, msg="当前部门下存在员工,请先将其移除再进行删除!")

        prg_ids = []
        self._iter_child(org, prg_ids)
        if prg_ids:
            _logger.info(f"级联删除子级部门{prg_ids}")

        return self.make_response(org.unlink())

    @http.route('/api/dt_organization/options', auth='token', methods=['GET'], type='jsonify')
    def options(self, org_id=None, **kwargs):
        model = http.request.env[self._model]
        domains = [('status', '=', True)]
        if org_id:
            # 去除当前组织下的所有组织
            prg_ids = [int(org_id)]
            org = model.sudo().browse(int(org_id))

            def _iter_child(org):
                for child in org.child_ids:
                    prg_ids.append(child.id)
                    _iter_child(child)

            _iter_child(org)
            domains.append(('id', 'not in', prg_ids))

        res = model.sudo().search_read(domains, fields=('id', 'name', 'parentId'), order="parentId desc,seq_no asc")
        for r in res:
            r['value'] = r['id']
            r['label'] = r['name']

        # 调整上下级关系
        org_map = {org['id']: org for org in res if org['parentId']}
        root_org_map = {org['id']: org for org in res if not org['parentId']}

        org_map_copy = deepcopy(org_map)
        for name, org in org_map_copy.items():
            if org['parentId'][0] in org_map:
                org_map[org['parentId'][0]].setdefault('children', []).append(org_map[name])
                # del org_map[name]

        for name, org in org_map.items():
            if org['parentId'][0] in root_org_map:
                root_org_map[org['parentId'][0]].setdefault("children", []).append(org)
            # else:
            #     root_org_map[name] = org

        if org_id in root_org_map:
            del root_org_map[org_id]
        return self.make_response(list(root_org_map.values()))
